package crane.bomb;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.ResourceBundle;

/**
 * 
 * @author wangqx
 *
 */
public class BombArray {

    /**
     * constructor
     *
     */
    public BombArray(){
    }
    
    /**
     * constructor
     * 
     * @param xLen
     * @param yLen
     * @param level
     */
    public BombArray(int xLen, int yLen, int level) {
        this.initArray(xLen, yLen, level);
    }

    /*
     * OPENED_BOMB
     */
    protected static String S_OPENED_BOMB;

    /*
     * CLOSED_BOMB
     */
    protected static String S_CLOSED_BOMB;

    /**
     * getProperties
     * 
     * @param key
     * @return String
     * @throws Exception
     */
    private static String getProperties(String key) throws Exception {
        ResourceBundle myResources = ResourceBundle.getBundle(
                "crane/bomb/label", Locale.getDefault());
        return myResources.getString(key);
    }
    
    static {

        try {
            BombArray.S_CLOSED_BOMB = BombArray
                    .getProperties("label_Closing_Pic");
            BombArray.S_OPENED_BOMB = BombArray
                    .getProperties("label_Opening_Pic");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * CHECKED_POINT_MAP
     */
    protected static Map CHECKED_POINT_MAP = new HashMap();

    /*
     * pointMap
     */
    private BombBean[][] _pointArray = null;

    /**
     * @return the pointArray
     */
    protected BombBean[][] getPointArray() {
        return _pointArray;
    }

    /**
     * @param pointArray the pointArray to set
     */
    protected void setPointArray(BombBean[][] pointArray) {
        this._pointArray = pointArray;
    }

    /**
     * get the point
     * 
     * @param x
     * @param y
     * @return PointBean
     */
    protected BombBean getPoint(int x, int y) {

        return this._pointArray[x][y];
    }

    /**
     * get the value of the point
     * 
     * @param x
     * @param y
     * @return value
     */
    protected int getValue(int x, int y) {

        return this._pointArray[x][y].getValue();
    }

    /**
     * _isBombed
     */
    private boolean _isBombed = false;

    /**
     * isBombed
     * @return isBombed
     */
    protected boolean isBombed() {
        return this._isBombed;
    }

    /**
     * isBombed
     * @param isBombed
     */
    protected void setBombed(boolean isBombed) {
        this._isBombed = isBombed;
    }
    
    /**
     * bombNum
     */
    private int bombNum = 0;
    
    /**
     * @return the bombNum
     */
    protected int getBombNum() {
        return bombNum;
    }

    /**
     * @param bombNum the bombNum to set
     */
    protected void setBombNum(int bombNum) {
        this.bombNum = bombNum;
    }
    
    
    /**
     * BOMB_REMAIN
     */
    private int bombRemain = 0;

    /**
     * @return the bombRemain
     */
    protected int getBombRemain() {
        return bombRemain;
    }

    /**
     * @param bombRemain the bombRemain to set
     */
    protected void setBombRemain(int bombRemain) {
        this.bombRemain = bombRemain;
    }

    /**
     * get the value of the point
     * 
     * @param xLen
     * @param yLen
     * @param level
     */
    private void initArray(int xLen, int yLen, int level) {

        // the number of the bomb
        int bombNum = Math.round(xLen * yLen * level / 10);        

        int randInt = 0;
        int xPoint = 0;
        int yPoint = 0;

        Random random = new Random();
        BombBean[][] pointArray = new BombBean[xLen][yLen];

        // set bomb
        int num = 0;
        BombBean pb = null;
        Map keyMap = new HashMap();
        while (num < bombNum) {

            randInt = random.nextInt(xLen * yLen);
            if (keyMap.containsKey(randInt + "")) {
                continue;
            }
            num++;
            keyMap.put(randInt + "", null);

            xPoint = new Double(randInt / yLen).intValue();
            yPoint = randInt - xPoint * yLen;

            pb = new BombBean(xPoint, yPoint);
            pb.setBomb(true);

            pointArray[xPoint][yPoint] = pb;
        }

        this._pointArray = pointArray;

        // set value
        this.initValue(xLen, yLen);

        // set Array into Point
        setArrayIntoPoint(xLen, yLen);
        // clear Checked point 
        BombArray.CHECKED_POINT_MAP.clear();
        
        setBombNum(bombNum);
        setBombRemain(bombNum);

    }

    /**
     * init the Array's value
     *
     * @param xLen
     * @param yLen
     */
    private void initValue(int xLen, int yLen) {

        BombBean[][] pointArray = this._pointArray;

        // set value
        int value = 0;
        BombBean pb = null;
        for (int x = 0; x < xLen; x++) {
            for (int y = 0; y < yLen; y++) {

                if (chkBomb(xLen, yLen, x - 1, y - 1)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x - 1, y)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x - 1, y + 1)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x, y - 1)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x, y + 1)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x + 1, y - 1)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x + 1, y)) {
                    value++;
                }

                if (chkBomb(xLen, yLen, x + 1, y + 1)) {
                    value++;
                }

                pb = pointArray[x][y];
                if (pb == null) {
                    pb = new BombBean(x, y);
                }
                pb.setValue(value);
                pointArray[x][y] = pb;

                value = 0;
            }
        }
    }

    /**
     * set Array into Point
     *
     * @param xLen
     * @param yLen
     */
    private void setArrayIntoPoint(int xLen, int yLen) {

        BombBean[][] pointArray = this._pointArray;
        BombBean pb = null;
        for (int x = 0; x < xLen; x++) {
            for (int y = 0; y < yLen; y++) {
                pb = pointArray[x][y];
                pb.setPointArray(pointArray);
            }
        }
    }

    /**
     * check if the point is a bomb
     * 
     * @param xLen
     * @param yLen
     * @param x
     * @param y
     * @return true: bomb, false: not a bomb
     */
    private boolean chkBomb(int xLen, int yLen, int x, int y) {

        if (x < 0 || x > xLen - 1) {
            return false;
        }

        if (y < 0 || y > yLen - 1) {
            return false;
        }

        if (this._pointArray[x][y] == null) {
            return false;
        }

        if (this._pointArray[x][y].isBomb()) {
            return true;
        }
        return false;
    }

}
